package com.example.tcp.server;


import com.example.tcp.server.example.ExampleDecoder;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.mqtt.MqttDecoder;
import io.netty.handler.codec.mqtt.MqttEncoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import java.util.List;
import java.util.function.Consumer;

@Slf4j
@SpringBootApplication
public class TcpServerApplication {

    public static void main(String[] args) throws InterruptedException {

        ConfigurableApplicationContext context = SpringApplication.run(TcpServerApplication.class, args);
        Handler handler = new Handler();

        int port = context.getEnvironment().getProperty("netty.tcp.port", Integer.class,9021);

        new Server().start(new Server.Config().setTcpPort(port), new Consumer<Channel>() {
            @Override
            public void accept(Channel channel) {
                channel.pipeline().addLast("Decoder", new ByteToMessageDecoder() {
                    @Override
                    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
                        context.getBean(DecoderFactory.class).decode(ctx, in, out);
                    }
                });
                channel.pipeline().addLast("Handler", handler);
            }
        });

        boolean mqttEnable = context.getEnvironment().getProperty("mqtt.enable", Boolean.class,true);

        if(mqttEnable) {
            int mqttPort = context.getEnvironment().getProperty("mqtt.port", Integer.class,1883);
            new Server().start(new Server.Config().setTcpPort(mqttPort), new Consumer<Channel>() {
                @Override
                public void accept(Channel channel) {
                    channel.pipeline().addLast("MqttDecoder", new MqttDecoder());
                    channel.pipeline().addLast("MqttEncoder", MqttEncoder.INSTANCE);
                    channel.pipeline().addLast("Handler", handler);
                }
            });
        }

    }

}
